package com.wsm.system.service.impl;

import com.wsm.system.domain.UserDO;
import com.wsm.system.domain.UserOnline;
import com.wsm.system.service.SessionService;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.DefaultSessionKey;
import org.apache.shiro.session.mgt.eis.SessionDAO;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.apache.shiro.subject.support.DefaultSubjectContext;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * 待完善
 *
 * @author wangshimin
 */
@Slf4j
@Service
public class SessionServiceImpl implements SessionService {
    private final SessionDAO sessionDAO;
    @Autowired
    DefaultWebSessionManager sessionManager;

    @Autowired
    public SessionServiceImpl(SessionDAO sessionDAO) {
        this.sessionDAO = sessionDAO;
    }

    @Override
    public List<UserOnline> list() {
        List<UserOnline> list = new ArrayList<>();
        Collection<Session> sessions = sessionDAO.getActiveSessions();
        UserOnline userOnline;
        for (Session session : sessions) {
            userOnline = new UserOnline();
            if (session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY) == null) {
                continue;
            } else {
                SimplePrincipalCollection principalCollection = (SimplePrincipalCollection) session
                        .getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY);
                UserDO userDO = (UserDO) principalCollection.getPrimaryPrincipal();
                userOnline.setUsername(userDO.getUsername());
            }
            userOnline.setId((String) session.getId());
            userOnline.setHost(session.getHost());
            userOnline.setStartTimestamp(session.getStartTimestamp());
            userOnline.setLastAccessTime(session.getLastAccessTime());
            userOnline.setTimeout(session.getTimeout());
            //状态
            if (null != session.getAttribute("force") && (boolean) session.getAttribute("force")) {
                userOnline.setStatus("forceLoginout");
            } else if (session.getAttribute("kickout") != null && (Boolean) session.getAttribute("kickout")) {
                userOnline.setStatus("kickout");
            }
            list.add(userOnline);
        }
        return list;
    }

    @Override
    public List<UserDO> listOnlineUser() {
        List<UserDO> list = new ArrayList<>();
        UserDO userDO;
        Collection<Session> sessions = sessionDAO.getActiveSessions();
        for (Session session : sessions) {
            SimplePrincipalCollection principalCollection;
            if (session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY) == null) {
                continue;
            } else {
                if (null != session.getAttribute("force") && (boolean) session.getAttribute("force")) {
                    continue;
                } else if (session.getAttribute("kickout") != null && (Boolean) session.getAttribute("kickout")) {
                    continue;
                }
                principalCollection = (SimplePrincipalCollection) session
                        .getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY);
                userDO = (UserDO) principalCollection.getPrimaryPrincipal();
                list.add(userDO);
            }
        }
        return list;
    }

    @Override
    public Collection<Session> sessionList() {
        return sessionDAO.getActiveSessions();
    }

    @Override
    public boolean forceLogout(String sessionId) {
        try {
            //获取被踢出的sessionId的session对象
            Session Session = sessionManager.getSession(new DefaultSessionKey(sessionId));
            if (Session != null) {
                //设置会话的kickout属性表示踢出了
                Session.setAttribute("force", true);
            }
        } catch (Exception e) {//ignore exception
            return false;
        }
        return true;
    }

    @Override
    public void login(long userId, Serializable sessionId) {
        UserDO userDO;
        Collection<Session> sessions = sessionDAO.getActiveSessions();
        for (Session session : sessions) {
            SimplePrincipalCollection principalCollection;
            if (session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY) == null) {
                continue;
            } else {
                principalCollection = (SimplePrincipalCollection) session
                        .getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY);
                userDO = (UserDO) principalCollection.getPrimaryPrincipal();
                if (userId == userDO.getUserId() && !(session.getId().equals(sessionId))) {
                    try {
                        sessionDAO.delete(session);
                    } catch (Exception e) {
                        log.error("删除已经登录过的session失败");
                    } finally {
                        break;
                    }
                }
            }
        }
    }

}
